import uuid
import requests as rq


class PlannerExecutionError(Exception):
    pass


class Planner:

    def __init__(self,
                 algo_type: str,
                 num_beams: int,
                 selected_container: dict) -> None:

        self.algo_type = algo_type
        self.num_beams = num_beams
        self.selected_container = selected_container

    def __translate_plans(self, result_payload: dict) -> dict:
        return dict(
            viewModeNames='any',   # required by the plan viewer
            **result_payload['response']
        )
    
    def __translate_input(self, input_dataset: list):
        return [
            {
                'item': {
                    "id": str(uuid.uuid4()).split('-')[0],
                    "source_id": "",
                    "group": "",
                    "dimension": [
                        float(cargo['length']),
                        float(cargo['width']),
                        float(cargo['height'])
                    ],
                    "weight": 0,
                    "load_bearing_capacity": 0,
                    "orientations": [0, 1, 2, 3, 4, 5],
                    "number": int(cargo['quantity']),
                    "layer_limitation": 0
                },
                'product': {
                    'type': 'default',
                    'art': cargo['name'],
                    "bearing_weight": 0,
                    "dest_port": "default",
                }
            } for cargo in input_dataset
        ]

    def compute(self, input_dataset: list) -> dict:
        payload = {
            'request': {
                'config': {
                    'algo_type': self.algo_type,
                    'planner': {
                        'num_beams': self.num_beams
                    }
                },
                'container': self.selected_container,
                'items': self.__translate_input(input_dataset)
            }
        }

        response = rq.post(
            'https://lite.doraclp.cn/api/v2/plan/',
            json=payload
        )

        if response.status_code != 200:
           msg = f'Status code = {response.status_code}; Message = {response.text}'
           raise PlannerExecutionError(msg)

        result_payload = response.json()
        return self.__translate_plans(result_payload)
